package thread

import (
	"strconv"
	"strings"
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/facade/runtime"
	"gitee.com/sansaniot/ssiot-core/logger"

	"ssforward/common/constant"
	"ssforward/common/utils"
	"ssforward/internal/forward/models"
)

type ForwardDetailThread struct {
}

func (ForwardDetailThread) Run(threadName string) {
	logger.Infof("启动线程 - %s.", threadName)
	go func() {
		for {
			select {
			case <-time.After(30 * time.Second):
				serverStats()
			}
		}
	}()
}

func serverStats() {
	db := runtime.Runtime.GetDbByKey("db")
	if db == nil {
		return
	}
	keyList := env.Cache.ScanKey(constant.ForwardClientPrefix + "*")
	if len(keyList) == 0 {
		return
	}
	forwardServerModel := &models.SysForwardServer{}
	forwardServerModel.Orm = db
	for _, key := range keyList {
		serverId := strings.Split(key, ":")[1]
		modMap := map[string]interface{}{}
		detailMap, _ := env.Cache.HashGetAll(key)
		if lastTime, ok := detailMap[constant.ForwardClientLastTime]; ok && len(lastTime) > 0 {
			modMap["last_forward_time"] = lastTime
		}
		if count, ok := detailMap[constant.ForwardClientSendCount]; ok && len(count) > 0 {
			modMap["forward_count"], _ = strconv.Atoi(count)
		}
		if status, ok := detailMap[constant.ForwardClientStatus]; ok && len(status) > 0 {
			modMap["connect_status"] = status
		}
		if len(modMap) > 0 {
			forwardServerModel.Id = serverId
			_ = forwardServerModel.ModMap(forwardServerModel, modMap)
		}
	}
	// 三三默认需要记录(方便独立部署配置false)
	enableDetailStr := env.ConfigOperator.GetString("service.forward.detail")
	enableDetail := utils.If(enableDetailStr == "false", false, true).(bool)
	if !enableDetail {
		return
	}
	// 记录转发条数
	insertDTList := make([]models.SysDataDetail, 0)
	for {
		detail := constant.DataDetailQueue.Dequeue()
		if detail == nil {
			break
		}
		if dataDetail, ok := detail.(models.SysDataDetail); ok {
			insertDTList = append(insertDTList, dataDetail)
		}
	}
	if len(insertDTList) > 0 {
		sysDataDetailModel := &models.SysDataDetail{}
		sysDataDetailModel.Orm = db
		if err := sysDataDetailModel.Add(&insertDTList); err != nil {
			env.Log.Error(err)
		}
	}
}
